/*
 * EventNetwork.cpp
 *
 *  Created on: Jun 3, 2010
 *      Author: sdaniele
 */
#include "common.h"
#include "../users/EventUser.h"
#include "../users/ImmediateNotifier.h"
#include "../users/DeltaNotifier.h"
#include "../users/TimedNotifier.h"
#include "../users/Canceller.h"
#include "../users/Sensitive.h"

#include "EventNetwork.h"
#include <vector>

#define true_or_err_and_exit(expr,msg)\
	if(!(expr)){\
		::std::cerr<<(msg)<<::std::endl;\
		exit(1);\
	}

namespace noti {

EventNetwork::EventNetwork(::std::string name, bool is_thread)
	:m_name(name),m_is_thread(is_thread),m_curr_clock(NULL),
	 m_clock_cnt(0),
	 m_immediate_cnt(0),
	 m_delta_cnt(0),
	 m_timed_cnt(0),
	 m_cancel_cnt(0),
	 m_sensitive_cnt(0)
{}

EventNetwork::~EventNetwork(){}

EventNetwork& EventNetwork::clock(const sc_clock* clk){
	m_curr_clock = clk;
	return *this;
}

#define curr_name(type)\
	(m_name+"_"#type"_"+intToStr(m_ ## type ## _cnt++))


EventNetwork& EventNetwork::immediate(size_t n){
	assert(n>0);
	true_or_err_and_exit(m_curr_clock,"set the clock first!");

	for(size_t i=0; i<n; i++)
		m_users.push_back( new ImmediateNotifier( curr_name(immediate), &m_event, m_curr_clock, m_is_thread) );
	return *this;
}

EventNetwork& EventNetwork::delta(size_t n){
	assert(n>0);
	true_or_err_and_exit(m_curr_clock,"set the clock first!");

	for(size_t i=0; i<n; i++)
		m_users.push_back( new DeltaNotifier( curr_name(delta), &m_event, m_curr_clock, m_is_thread) );
	return *this;
}


EventNetwork& EventNetwork::timed(size_t n, const sc_time& t){
	assert(n>0);
	true_or_err_and_exit(m_curr_clock,"set the clock first!");

	for(size_t i=0; i<n; i++)
		m_users.push_back( new TimedNotifier( curr_name(timed), &m_event, m_curr_clock, m_is_thread, t) );
	return *this;
}

EventNetwork& EventNetwork::cancel(size_t n){
	assert(n>0);
	true_or_err_and_exit(m_curr_clock,"set the clock first!");

	for(size_t i=0; i<n; i++)
		m_users.push_back( new Canceller( curr_name(cancel), &m_event, m_curr_clock, m_is_thread) );
	return *this;
}

EventNetwork& EventNetwork::sensitive(size_t n){	//clock is ignored, but must be not null
	assert(n>0);
	true_or_err_and_exit(m_curr_clock,"set the clock first!");

	for(size_t i=0; i<n; i++)
		m_users.push_back( new Sensitive( curr_name(sensitive), &m_event, m_curr_clock, m_is_thread) );
	return *this;
}

}
